發生在後端與資料庫之間的安全漏洞。駭客在輸入的字串中能夠夾帶SQL指令,並沒有過濾字串
通常是使用字串串聯方式來構成SQL的指令,若又在連線的時候使用權限過大的帳戶(工程師偷懶使用root或sa連接資料庫XD),甚至可以Get Shell
SQL-injection最經典的一部漫畫
媽媽接到電話,你好,我這邊是你兒子的學校,我們電腦出了點狀況
oh, 他用壞了甚麼東西嗎,媽媽問。 校方說: 可以這麼說
校方說: 你真的把你兒子取名為Robert'); DROP TABLE Students; --
嗎?
媽媽說: 是的,我們都叫他寶貝table
校方回說: 我們今年的學生資料都不見了,希望你覺得滿意。
媽媽說: 希望你以後會記得把寫進Table的資料清掉
sql = "SELECT * FROM users WHERE (name = '" + username + "') and (pw = '"+ password +"');";
db->execute(sql);
' OR 1=1 --
' OR 1=1 --
name = '1'
OR 1=1
False
or True
= True
--
為註解,目的是將無用的語句去掉
#
, /*
sql = "SELECT * FROM users WHERE (name = '' OR 1=1 --') and (pw = '' OR 1=1 --');";
db->execute(sql);
' OR 1=1; DROP TABLE Students; --
sql = "SELECT * FROM users WHERE (name = '' OR 1=1 --') and (pw = '' OR 1=1; DROP TABLE users --');";
db->execute(sql);
單純的過濾輸入,但駭客的手法百百種,他們能在有限的狀況下,又找出新的方法可以繞過
比較安全的作法
OR 1=1 --
和空的密碼做query,或是用;
截斷語句做其他事情$stmt = $pdo->prepare('SELECT * FROM employees WHERE name = :name');
$stmt->execute([ 'name' => $name ]);
foreach ($stmt as $row) {
// Do something with $row
}
$stmt = $dbConnection->prepare('SELECT * FROM employees WHERE name = ?');
$stmt->bind_param('s', $name); // 's' specifies the variable type => 'string'
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
// Do something with $row
}
參考自: https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php
參考自: https://www.it-swarm.dev/zh/sql/%E5%8F%82%E6%95%B0%E5%8C%96%E8%AF%AD%E5%8F%A5%E5%8F%AF%E4%BB%A5%E5%81%9C%E6%AD%A2%E6%89%80%E6%9C%89sql%E6%B3%A8%E5%85%A5%E5%90%97%EF%BC%9F/940507514/
我百分之百贊同「置換單引號不能杜絕SQL Injection,在某些特殊情境下會被攻破」,但在沒有強力佐證的情況下要說 「哼!換掉單引號根本沒屁用」 則略嫌浮誇。